%{
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "symboltable.h"
#include "version.h"

	void yyerror (char *);
	extern int yylval;
	extern char *yytag;
	extern int yyline;

	struct symbol *symbol_table = 0;
	int tempfile;
	int datawords = 0;
	int textwords = 0;
%}
%token ID
%token LT
%token GT
%token NUMBER 
%token SYMBOL
%token TEXT
%token DATA
%token SECTION
%token ACCESS
%token INVALID

%start object
%%
object: symboltable datasection textsection;

symboltable: SYMBOL entries
           | ;
entries: entry entries
       | ;
entry: name number section access {symbol_table = insert (symbol_table, yytag, $2, $3, $4);};
section: SECTION {$$ = yylval;}; 
access: ACCESS {$$ = yylval;};

datasection: DATA words
           | ;
words: dataword words
     | ;

textsection: TEXT instructions
           | ;

instructions: instruction instructions
            | ;

instruction: resolved {textwords ++; write (tempfile, &$1, 4);};
resolved: number {$$ = $1;}
        | unresolved {$$ = $1;};

unresolved: lookup number {$$ = $1 | $2;};
lookup: LT name_ref GT {$$ = $2;};

name_ref: ID {$$ = lookup_by_name (symbol_table, yytag)->address;};
name: ID;
dataword: NUMBER {datawords ++; write (tempfile, &yylval, 4);};
number: NUMBER {$$ = yylval;};

%%

void yyerror (char *message)
{
	fprintf (stderr, "***generate line %d: %s\n", yyline, message);
}

int main (int argc, char **argv)
{
	int version = GAX_VERSION;
	char tempfilename [32];
	char buf [1024];
	int c;
	if (argc > 1)
	{
		close (0);
		open (argv [1], O_RDONLY);
	}
	sprintf (tempfilename, "tmp%d.tmp", getpid ());
	tempfile = open (tempfilename, O_WRONLY | O_CREAT, 0644);
	yyparse ();
	close (tempfile);
	tempfile = open (tempfilename, O_RDONLY);
	write (1, &version, 4);
	write (1, &datawords, 4);
	write (1, &textwords, 4);
	while (c = read (tempfile, buf, 1024))
	{
		write (1, buf, c);
	}
	close (tempfile);
	unlink (tempfilename);
	return 0;
}

